文章目录
  1. 1. Apache Drill教程和MapR沙箱
  2. 2. 浏览用例数据
  3. 3. 浏览日志数据
  4. 4. 浏览Hive上订单表(Orders)数据
  5. 5. 浏览HBase的产品表(Products)
  6. 6. Drill REST接口

根据福雷斯特研究公司(Forrester Research)的观点,SQL将成为Hadoop生态系统中最多产的应用方案之一。Apache Drill 是一个应用于大数据搜索的开源SQL查询引擎。REST服务和客户端已经成为互联网流行的技术。 Apache HBase则是一个广受欢迎的Hadoop NoSQL数据库。在本文中,我将结合 SQL、Hadoop、Drill、REST with JSON、NoSQL 及 HBase 等技术,讨论并展示如何使用 Drill REST API来查询 HBase 和 Hive。同时我也会分享一个使用Drill REST API的简单jQuery客户端,利用JSON做数据交换,提供给用户一个基本的操作界面。

Apache Drill教程和MapR沙箱

Apache Drill提供了直接查询文件中自描述和半结构化数据(类似与JSON和Parquet)以及HBase表的功能,并且查询HBase表时无需在类似Hive元存储的集中式存储中定义和维护表的模式。这个例子是建立在使用Drill的MapR沙箱和Drill教程中示例数据基础上的。含有Apache Drill的MapR沙箱是一个功能全面,单节点的集群,它可以让你在一个Hadoop环境中了解Apache Drill的概况。

浏览用例数据

Drill教程中的案例是一个在线零售系统,用户可以通过Web的界面和手机应用来购买商品。主要的客户概要信息和产品目录在MapR-DB中管理,这是一个NoSQL的HBase数据库。来自网页端和手机应用端的点击流数据以JSON格式文件的形式存储在Hadoop中,订单数据则是存储在Hive中。通过Drill,我们可以动态查询这些不同数据源,而且甚至可以结合不同的数据源查询。下面的关系图展示了该教程中不同数据源之间的“关系”。



浏览日志数据

利用Drill,你可以对文件和目录直接执行SQL操作,而无需做预先模式定义或者任何模型更改的模式管理动作。查询的同时也能得到相应的模式。下图是使用Drill Explorer来浏览JSON数据,无需定义和管理任何集中的模式。



下面的例子是对一个JSON文件执行SQL语句,查询事务id、设备名称和以cr开头的关键字。



浏览Hive上订单表(Orders)数据

下面的例子是使用Drill Explorer来浏览Hive的order表。Drill可以在不用Hive执行引擎的条件下使用Hive元存储。



浏览HBase的产品表(Products)

HBase是一个NoSQL数据库。MapR-DB是一个企业级的Hadoop NoSQL数据库,它实现了HBase的API,并将其开放以支持应用开发。MapR-DB的使用起来就和HBase一样,但底层实现更为高效,而且它与MapR文件系统是集成的。HBase是一个面向列族的数据库,且是“无模式”的,这意味着当你创建一个表的时候只需要定义列族。在你写数据的时候,列会被动态定义,并且数据都以字节数组的形式存储,而非输入时的类型。

HBase的产品表(products)有两个列族(下图中的details和pricing):



如果查询HBase采用Hive或其他基于Hadoop的SQL(SQL-on-Hadoop)方式,你不得不包装一个模式定义以此明确如何转换二进制的值。不像其他基于Hadoop的SQL方式,Drill在Hive中不需要包装模式定义来操作HBase数据。你可以像如下使用Drill explorer来浏览HBase中产品(products)表。



这是一个使用Drill命令行界面来查询HBase中产品(products)表的示例。

0: jdbc:drill:> select * from maprdb.products limit 3;
+------------+------------+------------+
| row_key | details | pricing |
+------------+------------+------------+
| [B@1babffd6 | {"category":"bGFwdG9w","name":"IlNvbnkgbm90ZWJvb2si"} | {"price":"OTU5"} |
| [B@456a24be | {"category":"RW52ZWxvcGVz","name":"IzEwLTQgMS84IHggOSAxLzIgUHJlbWl1bSBEaWFnb25hbCBTZWFtIEVudmVsb3Blcw=="} | {"price":"MTY="} |
| [B@3b92598c | {"category":"U3RvcmFnZSAmIE9yZ2FuaXphdGlvbg==","name":"MjQgQ2FwYWNpdHkgTWF4aSBEYXRhIEJpbmRlciBSYWNrc1BlYXJs"} | {"price":"MjEx"} |
+------------+------------+------------+

鉴于HBase中任何数据都是以字节数组存储的,以及Drill不需要预先的模式定义来指明数据类型,查询所返回列值的原始字节数组与其存储状态时一致。通过Drill,你可以使用convert_from函数将数据转换到相应的数据类型。另外,列可以像这样指定别名:



为了避免反复写入冗长且复杂的HBase查询语句,通用的工作流程是先创建一个包含有用信息的视图,然后再查询该视图。在ODBC工具,JDBC客户端或本例中的REST客户端中,视图可以使数据以更可用的”表格”形式来便于使用。REST客户端所用的视图是如上所示经过转换与Hive表连接的HBase数据。这是一个基于HBase数据创建视图的查询:

首先切换到可写的工作区:

0: jdbc:drill:> use dfs.mydata;
+------------+------------+

| ok | summary |
+------------+------------+

| true | Default schema changed to 'dfs.mydata' |
+------------+------------+

1 row selected (0.078 seconds)

创建一个HBase中产品表(Products)的视图:


0: jdbc:drill:> create or replace view prodview as SELECT CAST(row_key AS INTEGER) AS prod_id, CAST(t.details.category AS VARCHAR(40)) AS category, CAST(t.details.name AS VARCHAR(129)) AS name FROM maprdb.products t;
+------------+------------+

| ok | summary |
+------------+------------+

| true | View 'prodview' replaced successfully in 'dfs.mydata' schema |
+------------+------------+

与传统数据库所不同,视图通常都是由DBA/开发人员来操作,Drill中基于文件系统的视图是非常轻量的。一个Drill视图事实上是在一个简单的JSON 文件中定义的虚拟数据集。来看看创建的JSON文件:

# cat /mapr/demo.mapr.com/data/views/prodview.view.drill
{
"name" : "prodview",
"sql" : "SELECT CAST(`row_key` AS INTEGER) AS `prod_id`, CAST(`t`.`details`['category'] AS VARCHAR(40)) AS `category`, CAST(`t`.`details`['name'] AS VARCHAR(129)) AS `name`nFROM `maprdb`.`products` AS `t`",
"fields" : [ {
"name" : "prod_id",
"type" : "INTEGER"
}, {
"name" : "category",
"type" : "VARCHAR",
"precision" : 40
}, {
"name" : "name",
"type" : "VARCHAR",
"precision" : 129
} ],
"workspaceSchemaPath" : [ "dfs", "mydata" ]
}

你可以像下面一样使用Drill explorer来浏览产品视图表(prodview):



在查询中关联Hive的订单表(Orders)和产品视图表(Prodview)



通过Drill,我们可以在查询中动态地关联Hive、文件和HBase表。举个例子,该查询是从json日志文件中获取device和prod_id,从Hive的订单表中获取order,其中json日志文件的prod_id等于order表中的prod_id。【译者注:原文作者笔误,将查询条件的prod_id写成了cust_id。】

创建一个视图orderprodview,连接HBase的产品表视图(prodview)

【译者注:此处原文作者有误,写的是产品表product】和Hive的订单表(Order):

0: jdbc:drill:> create or replace view orderprodview as select o.order_id, o.`month`, o.cust_id, o.state, o.prod_id, o.order_total, p.category, p.name from hive.orders o, dfs.mydata.prodview p where o.prod_id=p.prod_id limit 100;
+------------+------------+

| ok | summary |
+------------+------------+

| true | View 'orderprodview' replaced successfully in 'dfs.mydata' schema |
+------------+------------+

这是查询视图orderprodview的例子:



Drill视图的用途如下:

简化复杂查询
从多种数据源中聚合数据
与表一样
配有像Tableau一样的BI(Business Intelligence)工具
数据管理灵活
接下来,让我们看看在REST中如何使用这个视图

Drill REST接口

Drill提供了一个简单的REST接口,你可以从Drill wiki上了解到更多https://cwiki.apache.org/confluence/display/DRILL/Apache+Drill+Wiki。这是提交一个查询并收到结果的REST API。你可以通过HTTP POST请求到Drill URL,即:8047/query.json,body携带一个JSON格式的Request,如下图所示。你所收到的response响应将是一个JSON对象列表。

POST <drill_node_ip_address>:8047/query.json
Request body:
{
"queryType" : "SQL",
"query" : "select * from dfs.mydata.orderprodview limit 5”
}
Response body (list of JSON objects):
[
{
"order_total" : 13,
"category" : "Binders and Binder Accessories",
"prod_id" : 909,
"name" : "Wilson Jones Ledger-SizePiano-Hinge Binder2Blue",
"state" : "ca", }, …
]

使用CURL或者浏览器插件来测试REST接口非常方便。下面这个例子就是从Linux命令行用CURL来发送对orderprodview的查询:

# curl 
--header "Content-type: application/json"
--request POST
--data '{
"queryType" : "SQL",
"query" : "select * from dfs.mydata.orderprodview limit 1"
}'

http://192.168.110.133:8047/query.json

[ {
"order_total" : 13,
"category" : "Binders and Binder Accessories",
"prod_id" : 909,
"name" : "Wilson Jones Ledger-SizePiano-Hinge Binder2Blue",
"state" : "ca",
"month" : "June",
"order_id" : 67212,
"cust_id" : 10001
}]

这是使用Google Chrome的一个REST Client扩展来查询orderprodview:









使用Drill REST接口查询订单产品视图的JQuery客户端

现在我们来看看为刚刚的REST查询而做的一个简单JQuery客户端。这是客户端的一个截图。它发起查询给Drill并且在一个表格中展示出了结果。


使用Google Chrome开发者工具,你可以看到HTTP请求如下所示:



而返回的response如下:



一个jQuery客户端

这是参与服务调用的jQuery代码。jQuery客户端使用jquery.ajax来执行HTTP POST到Drill查询URL,将查询数据以JSON的格式传递过去。

var rootURL = "http://host:8047/query.json";
var query = "select * from dfs.mydata.orderprodview"

function doQuery(query) {
console.log('doQuery');
$.ajax({
type: 'POST',
contentType: 'application/json',
url: rootURL,
dataType: "json",
data: queryToJSON(query),
success: function(data) {
console.log(' success: ' + data);
renderList(data);
},
error: function(jqXHR, textStatus, errorThrown) {
alert('error: ' + textStatus);
}
});
}
function queryToJSON(query) {
return JSON.stringify({
"queryType": "SQL",
"query": query
});
}

如果请求成功,renderList会被调用,该方法如下所示。返回的response数据是一个JSON对象数据,renderList会把订单对象添加到index.html页面的html表格中。

function renderList(data) {
var list = data == null ? [] : (data instanceof Array ? data : [data])
$.each(list, function(order) {
$('#orderList').append('<tr><td>' + order.order_id + '</td><td>'
+ order.cust_id + '</td><td>'
+ order.state + '</td><td>' + order.month + '</td><td>'
+ order.order_total + '</td><td>'
+ order.prod_id + '</td><td>' + order.category + '</td><td>'
+ order.name + '</td></tr>');
});
}

Index.html
<table id="list" class='tablesorter-blue'>
<thead>
<tr>
<th>< b>Order Id</b></th>
<th>< b>Customer Id</b></th>
<th>< b>State</b></th>
<th>< b>Month</b></th>
<th>< b>Order Total</b></th>
<th>< b>Product Id</b></th>
<th>< b>Product Category</b></th>
<th>< b>Product Name</b></th>
</tr>
</thead>
<tbody id="orderList" ></tbody>
</table>

jQuery客户端还提供了搜索产品类目(Product Category)的功能,如下图。



搜索功能的代码只是在查询中添加了where category like ‘searchKey’:

function search(searchKey) {
if (searchKey != '')
query = query + ' where category like '' + searchKey + '%'';
doQuery(query);
}

在Chrome开发者工具窗口看到的JSON请求数据是这样的:



以上的例子包含了一个简单的REST客户端,它采用Drill REST API来动态查询HBase和Hive。

想要了解更多如何使用Drill的示例,下载MapR沙箱,然后尝试一下Drill沙箱教程。更多信息可到Apache Drill官方网站获取。

文章目录
  1. 1. Apache Drill教程和MapR沙箱
  2. 2. 浏览用例数据
  3. 3. 浏览日志数据
  4. 4. 浏览Hive上订单表(Orders)数据
  5. 5. 浏览HBase的产品表(Products)
  6. 6. Drill REST接口